from django.shortcuts import render, redirect, HttpResponse
from goodsapp.models import *
from hashlib import sha1
from django.http import JsonResponse
from django.core.paginator import Paginator
from django.db.models import Sum
import time
import os
from django.db import transaction
from alipay import AliPay
from django.conf import settings

# Create your views here.
alipay = AliPay(
    appid=settings.ALIPAY_APPID,
    app_notify_url=None,
    app_private_key_path=os.path.join(settings.STATICFILES_DIRS[0], 'app_private_key.pem'),
    alipay_public_key_path=os.path.join(settings.STATICFILES_DIRS[0], 'alipay_public_key.pem'),
    sign_type='RSA',
    debug=True,
)

# 首页
def index(request):
    goodstype = TypeInfo.objects.all()
    list1 = []
    c = {}
    for type in goodstype:
        fire = type.goodsinfo_set.order_by('-gclick')[0:4]
        id = type.goodsinfo_set.order_by('-id')[0:3]
        list1.append({'type': type, 'fire': fire, 'id': id})

    # 显示我的购物车商品数量
    if request.session.get('user_names'):
        user_names = request.session.get('user_names')
        cid = Usermessage.objects.get(user_name=user_names).id
        c = CarInfo.objects.filter(user_id=cid).aggregate(Sum('count'))
    return render(request, 'goodsapp/index.html', {'list1': list1, 'count': c.get('count__sum')})


# 定义一个判断登录状态的装饰器
def is_login(func):
    def inner(request, *args, **kwargs):
        if request.session.get('user_names'):
            return func(request, *args, **kwargs)
        else:
            return redirect('/login/')

    return inner


# 登录页面
def login(request):
    if request.method == 'GET':
        # 虽然session可以存中文用户名，单退出登录会被清除，还是用cookie比较好。
        # if request.session.get('user_name'):
        #     user_name = request.session.get('user_name')
        if request.COOKIES.get('user_name'):
            user_name = request.COOKIES.get('user_name')
        else:
            user_name = ''
        return render(request, 'goodsapp/login.html', {'user_name': user_name})


# 登录过程
def login1(request):
    # 获取用户表单提交的数据
    if request.method == 'POST':
        dict1 = request.POST
        user_name = dict1.get('username')
        pswd = dict1.get('pswd')

        # 将密码加密与数据库比较寻找
        s = sha1()
        s.update(pswd.encode())
        pswd_sha1 = s.hexdigest()

        # 获取数据库数据，判断用户名和密码是否正确
        if Usermessage.objects.filter(user_name=user_name, password=pswd_sha1):
            # 勾选记住用户名，发一个session
            res = redirect('/user_center_info/')
            if dict1.get('rem') == 'on':
                res.set_cookie('user_name', user_name)  # cookie不能发值为中文内容的字符串，用户名不能有中文。
                # request.session['user_name'] = user_name #记住用户名这种尽量用cookie存储
            request.session['user_names'] = user_name  # 用户登录记录
            return res
        else:
            return render(request, 'goodsapp/login.html', {'fail': 1})


# 退出登录
def logout(request):
    request.session.flush()
    user_name = ''
    if request.method == 'GET':
        if request.COOKIES.get('user_name'):
            user_name = request.COOKIES.get('user_name')
    return render(request, 'goodsapp/login.html', {'user_name': user_name})


# 注册页面
def register(request):
    return render(request, 'goodsapp/register.html')


# 注册过程
def register1(request):
    # 获取提交的用户注册数据
    if request.method == 'POST':
        dict1 = request.POST
        user_name = dict1.get('user_name')
        pswd = dict1.get('pwd')
        cpswd = dict1.get('cpwd')
        email = dict1.get('email')
        if not Usermessage.objects.filter(user_name=user_name):  # 判断用户名是否已存在
            if pswd == cpswd and dict1.get('allow') == 'on':  # 判断两密码输入是否相同和是否勾选协议
                # 对数据（密码）进行sha1加密
                s = sha1()
                s.update(pswd.encode())
                pswd_sha1 = s.hexdigest()

                # 将数据存入数据库
                usermes = Usermessage()
                usermes.user_name = user_name
                usermes.password = pswd_sha1
                usermes.email = email
                usermes.save()
                return render(request, 'goodsapp/register.html', {'fail': 1})
            else:
                return render(request, 'goodsapp/register.html', {'fail': 3})
        else:
            return render(request, 'goodsapp/register.html', {'fail': 2})


# 用户中心页面，最近浏览。
@is_login
def user_center_info(request):
    # 最近浏览
    jin = request.COOKIES.get('jin', '[]')
    jin_list = eval(jin)
    # [30, 29, 10]
    goods = [GoodsInfo.objects.get(pk=id) for id in jin_list]

    # 进入用户中心界面，获取数据库用户信息
    if request.method == 'GET':
        user_name = request.session.get('user_names')  # 获取登录的用户名
        user1 = Usermessage.objects.get(user_name=user_name)  # 找到登录用户的信息对象
        user_phone = user1.phone  # 获取电话
        user_home = user1.home  # 获取地址
        return render(request, 'goodsapp/user_center_info.html',
                      {'user_name': user_name, 'user_phone': user_phone, 'user_home': user_home, 'goods': goods})

    # 获取用户修改/完善的个人信息
    else:
        # 获取用户表单提交的数据
        user_name = request.session.get('user_names')
        dict1 = request.POST
        phone = dict1.get('phone')
        home = dict1.get('home')

        # 向指定用户添加用户信息到数据库
        user2 = Usermessage.objects.get(user_name=user_name)  # 找到登录用户的信息对象
        user2.phone = phone  # 修改电话
        user2.home = home  # 修改地址
        user2.save()
        return render(request, 'goodsapp/user_center_info.html',
                      {'user_name': user_name, 'user_phone': user2.phone, 'user_home': user2.home, 'goods': goods})


# 用户中心-用户个人信息修改页面
@is_login
def user_center_info_change(request):
    return render(request, 'goodsapp/user_center_info_change.html')


# 我的购物车页面
@is_login
def cart(request):
    # goodslist = CarInfo.objects.all()  #错误！！！会把所有用户的goods都读出来
    user_names = request.session.get('user_names')
    goodslist = CarInfo.objects.filter(user_id=Usermessage.objects.get(user_name=user_names).id)
    return render(request, 'goodsapp/cart.html', {'goodslist': goodslist})


# 加入购物车时数据库的数据存储
@is_login
def carts(request):
    user_names = request.session.get('user_names')
    dict1 = request.GET
    gid = dict1.get('gid')
    inum1 = int(dict1.get('inum1'))
    id = Usermessage.objects.get(user_name=user_names).id

    # 判断当前商品是否已经在该用户购物车中
    carts = CarInfo.objects.filter(user_id=id, goods_id=gid)
    if carts:
        cars = carts[0]
        cars.count += inum1
        cars.save()
    else:
        cars = CarInfo()
        cars.user_id = id
        cars.goods_id = gid
        cars.count = inum1
        cars.save()
    c = CarInfo.objects.filter(user_id=id).aggregate(Sum('count'))
    return JsonResponse({'login': 1, 'ccount': c.get('count__sum')})


# 编辑购物车中商品数量和金额，并于数据库交互
def edit(request):
    dict1 = request.GET
    cid = dict1.get('cid')
    count = dict1.get('count')
    cart = CarInfo.objects.get(id=cid)
    cart.count = count
    cart.save()
    return JsonResponse({'ok': 1})


# 删除购物车中指定商品，并与数据库交互
def remove(request):
    dict1 = request.GET
    cid = dict1.get('cid')
    cart = CarInfo.objects.get(id=cid)
    cart.delete()
    return JsonResponse({'ok': 1})


# 我的订单页面
@is_login
def user_center_order(request):
    user_names = request.session.get('user_names')
    user = Usermessage.objects.get(user_name=user_names)
    order = OrderInfo.objects.filter(user_id=user.id)
    return render(request, 'goodsapp/user_center_order.html',{"orders":order})


# 收货地址页面
@is_login
def user_center_site(request):
    if request.method == 'GET':
        user_name = request.session.get('user_names')
        addres = Goodsarea.objects.filter(auser_id=Usermessage.objects.get(user_name=user_name).id)
        return render(request, 'goodsapp/user_center_site.html', {'addres': addres})
    else:
        user_name = request.session.get('user_names')
        users = Usermessage.objects.get(user_name=user_name)
        dict1 = request.POST
        aname = dict1.get('aname')
        ahome = dict1.get('ahome')
        aemailnum = dict1.get('aemailnum')
        aphone = dict1.get('aphone')

        areas = Goodsarea()
        areas.aname = aname
        areas.ahome = ahome
        areas.aemailnum = aemailnum
        areas.aphone = aphone
        areas.auser_id = users.id
        areas.save()
        return render(request, 'goodsapp/user_center_site_change.html')


# 收货地址修改提交完成页面
@is_login
def user_center_site_change(request):
    return render(request, 'goodsapp/user_center_site_change.html')


# 商品列表页面
def list(request, id, pagenum,ord):
    user_names = request.session.get('user_names')
    gid = id
    uid = Usermessage.objects.get(user_name=user_names).id

    # 判断当前商品是否已经在该用户购物车中
    carts = CarInfo.objects.filter(user_id=uid, goods_id=gid)
    if carts:
        cars = carts[0]
        cars.count += 1
        cars.save()
    else:
        cars = CarInfo()
        cars.user_id = uid
        cars.goods_id = gid
        cars.count = 1
        cars.save()
    lists = f'/lists{id}_{pagenum}_{ord}/'
    return redirect(lists)


# 商品列表页面(可选择，分页，排序)
# def lists(request, id, page_num, ord):
#     goodslist = GoodsInfo.objects.filter(gtype_id=id)
#     type_info = TypeInfo.objects.get(id=id)
#     gnew = type_info.goodsinfo_set.order_by('-id')[0:2]
#     # c = {}
#     # # 显示我的购物车商品数量
#     # if request.session.get('user_names'):
#     #     user_names = request.session.get('user_names')
#     #     cid = Usermessage.objects.get(user_name=user_names).id
#     #     c = CarInfo.objects.filter(user_id=cid).aggregate(Sum('count'))
#
#     # 按照规则排序
#     order = '-id'
#     if ord == '1':
#         order = 'gprice'
#     elif ord == '2':
#         order = '-gclick'
#     goodes = type_info.goodsinfo_set.order_by(order)
#     p = Paginator(goodes, 10)
#     page = p.page(int(page_num))
#
#     contents = {
#         'goodsres': goodslist,
#         'page': page,
#         'type_info': type_info,
#         'goodes': goodes,
#         'ord': ord,
#         # 'count': c.get('count__sum'),
#     }
#     print(id,page_num,ord,order)
#     return render(request, 'goodsapp/list.html', contents)
def lists(request, id, page_num, ord):

    # goods = GoodsInfo.objects.filter(gtype_id=id)  # 查找当前分类中所有商品
    type_info = TypeInfo.objects.get(id=id)  # 当前分类
    gnew = type_info.goodsinfo_set.order_by('-id')[0:2]  # 新品推荐

    # 按照规则排序
    order = '-id'
    if ord == '1':
        order = '-gprice'
    elif ord == '2':
        order = '-gclick'
    goods = type_info.goodsinfo_set.order_by(order)  # 按照对应的方式获取商品并按照传入的参数排序
    p = Paginator(goods, 10)
    page = p.page(int(page_num))

    context = {'title': '列表', 'isCart': 1, 'goods': goods, 'type': type_info, 'gnew': gnew, 'page': page, 'ord': ord}
    return render(request, 'goodsapp/list.html', context)



# 商品详情页面
def detail(request, id):
    # 获取商品信息并展示在页面上
    goodsmes = GoodsInfo.objects.get(id=id)
    gtitle = goodsmes.gtitle
    gcontent = goodsmes.gcontent
    gprice = goodsmes.gprice
    gunit = goodsmes.gunit
    gpic = goodsmes.gpic
    gid = goodsmes.id

    # 商品点击量+1
    goodsmes.gclick += 1
    goodsmes.save()

    # 显示我的购物车商品数量
    if request.session.get('user_names'):
        user_names = request.session.get('user_names')
        cid = Usermessage.objects.get(user_name=user_names).id
        c = CarInfo.objects.filter(user_id=cid).aggregate(Sum('count'))
        islogins = 1
    else:
        islogins = 2
        c = {'count__sum': 0}

    contents = {
        'gtitle': gtitle,
        'gcontent': gcontent,
        'gprice': gprice,
        'gunit': gunit,
        'gpic': gpic,
        'gid': gid,
        'c': c.get('count__sum'),
        'islogins': islogins,
    }
    res = render(request, 'goodsapp/detail.html', contents)
    # 返回结束前需要执行的    （关于return res理解，注意看9-17-10点左右回放，老师的解释）
    jin = request.COOKIES.get('jin', '[]')
    jin_list = eval(jin)
    if jin:
        if not id in jin_list:
            jin_list.insert(0, id)
            if len(jin_list) > 5:
                jin_list.pop()
    res.set_cookie('jin', str(jin_list))
    return res


# 订单提交页面
@is_login
def place_order(request):
    return render(request, 'goodsapp/place_order.html')


# 获取单个购买的商品信息
def index12(request):
    res = request.GET
    gid = res.get('gid')
    inum1 = res.get('inum1')
    # print(inum1, gid)
    # print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
    request.session['gid'] = gid
    request.session['inum1'] = inum1
    return JsonResponse({'islogin': 1})


# 单个购买时的订单页面显示
@is_login
def place_order1(request):
    gid = request.session.get('gid')
    inum1 = request.session.get('inum1')
    goods = GoodsInfo.objects.get(id=gid)
    gpic = goods.gpic
    gtitle = goods.gtitle
    gunit = goods.gunit
    gprice = goods.gprice
    sumprice = int(inum1) * float(gprice)
    sumprices = int(inum1) * float(gprice) + 10
    placeorder = 1

    user_names = request.session.get('user_names')
    uid = Usermessage.objects.get(user_name=user_names).id

    areas = Goodsarea.objects.filter(auser_id=uid)
    garea = ''
    if areas:
        area = 1
        a = areas[0]
        garea = f'{a.ahome} ({a.aname} 收) {a.aphone}'
    else:
        area = 0

    contents = {
        'inum1': inum1,
        'gpic': gpic,
        'gtitle': gtitle,
        'gunit': gunit,
        'gprice': gprice,
        'sumprice': sumprice,
        'sumprices': sumprices,
        'placeorder': placeorder,
        'garea': garea,
        'area': area,
    }

    return render(request, 'goodsapp/place_order.html', contents)


# 单个购买时的订单提交
@is_login
def place_order_submit(request):
    gid = request.session.get('gid')
    inum1 = request.session.get('inum1')
    goods = GoodsInfo.objects.get(id=gid)
    gprice = goods.gprice
    sumprices = int(inum1) * float(gprice) + 10

    user_names = request.session.get('user_names')
    user = Usermessage.objects.get(user_name=user_names)

    goods_area = Goodsarea.objects.filter(auser_id=user.id)
    ahome = goods_area[0].ahome

    order = OrderInfo()
    oids = str(int(time.time() * 1000)) + str(user.id)
    order.oid = oids
    order.user_id = user.id
    order.ototal = sumprices
    order.oaddress = ahome
    order.save()

    return redirect('/user_center_order/')


# 购物车多个商品结算订单
@is_login
def place_order2(request):
    cids = request.GET.getlist('cid')  # 得到购物车 页面提交的购物车 的id
    goodslist = CarInfo.objects.filter(id__in=cids)  # 找到所有的购物车对象
    for cart in goodslist:
        amount = cart.count * cart.goods.gprice
        cart.amount = amount
    user_names = request.session.get('user_names')
    uid = Usermessage.objects.get(user_name=user_names).id
    # goodslist = CarInfo.objects.filter(user_id=Usermessage.objects.get(user_name=user_names).id)
    placeorder = 0

    areas = Goodsarea.objects.filter(auser_id=uid)
    garea = ''
    if areas:
        area = 1
        a = areas[0]
        garea = f'{a.ahome} ({a.aname} 收) {a.aphone}'
    else:
        area = 0

    total = 0
    for cg in cids:
        cgoods = CarInfo.objects.get(id=cg)
        count = cgoods.count
        price = cgoods.goods.gprice
        total = total + count * price
    # ftotal = sum(totals)
    ytotal = total + 10

    return render(request, 'goodsapp/place_order.html',
                  {'goodslist': goodslist, 'placeorder': placeorder, 'garea': garea, 'area': area, 'ftotal': total,
                   'ytotal': ytotal})


# 购物车多个商品结算订单提交：
@is_login
def place_order2_submit(request):
    return redirect('/')


@transaction.atomic
def do_order(request):
    pay_style = request.GET.get('pay_style')
    cids = request.GET.getlist('cid')  # 购物车商品的id
    addr = request.GET.get('addr')
    # ototal = request.GET.get('ototal')

    user_names = request.session.get('user_names')
    uid = Usermessage.objects.get(user_name=user_names).id

    # 开启事务
    sid = transaction.savepoint()  # 存档点
    # 创建订单
    order = OrderInfo()
    order.oid = str(int(time.time() * 1000)) + str(uid)  # 订单编号
    order.user_id = uid
    # order.ototal = ototal   #订单金额
    order.ototal = 0  # 订单金额
    order.oaddress = addr
    order.save()

    cart_list = CarInfo.objects.filter(id__in=cids)
    total = 0
    isok = True
    for cart in cart_list:
        if cart.count <= cart.goods.gkucun:
            # 库存充足
            detail = OrderDetailInfo()
            detail.order_id = order.oid
            detail.goods_id = cart.goods.id
            detail.price = cart.goods.gprice
            detail.count = cart.count
            detail.save()

            total += detail.count * detail.price  # 计算总价
            cart.goods.gkucun -= cart.count  # 更改库存
            cart.goods.save()

            cart.delete() #删除购物车对象
        else:
            # 库存不足
            isok = False
            break
    if isok:
        # 最终提交订单
        order.ototal = total + 10  # 订单总价
        # 订单成功
        if pay_style == 'cash':  # 到付
            order.oispay = 1
            order.save()
            transaction.savepoint_commit(sid)  # 提交事务
            return JsonResponse({'res': 1})
        else:
            # 支付宝支付
            order_id = order.oid  # 订单编号
            total_pay = order.ototal  # 支付的总价
            # total_pay = 9.9 #测试着自己定个数，之后注释掉
            # 构造一个提交给支付宝的string
            order_string = alipay.api_alipay_trade_page_pay(
                out_trade_no=order_id,
                total_amount=str(total_pay),
                subject=f'每日生鲜{order_id}',  # 订单主题
                # 支付完成后打开的页面。因为我们还要验证有没有支付成功的，填自己上线网站的地址，
                # 这个地址是支付宝完成后帮我们打开的，所以要写的是公网的地址；目前我们还在开发测试项目，所以写127.0.。。
                return_url='http://127.0.0.1:8000/order/check_pay/?order_id=' + order_id,
                # 验证网址，原则上同上
                notify_url='http://127.0.0.1:8000/order/check_pay/?order_id=' + order_id,
            )
            alipay_url = settings.ALIPAY_URL + '?' + order_string  # 在alipay的url后加上发的内容，发送过去
            return JsonResponse({'res': 3, 'pay_url': alipay_url})  # 给前端返回支付链接
    else:
        # 订单失败
        transaction.savepoint_rollback(sid)
        return JsonResponse({'res': 0})


def count1(request):
    # 单独负责统计数量
    c = CarInfo.objects.filter(user_id=request.session.get('user_id')).aggregate(Sum('count'))
    print(c.get('count__sum'))
    return JsonResponse({'count': c.get('count__sum')})
